﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Data;
using System.DirectoryServices;

namespace Ko
{
    public class AD_Helper
    {

        #region Members

        Ko.KoEnvironment koEnv = new Ko.KoEnvironment();

        #endregion

        #region App Settings
        public string GetAppSetting(String mName)
        {
            return koEnv.GetAppSetting(mName);
        }
        #endregion App Settings

        public Exception IsExistUserInGroup(ref Boolean IsExist, string uid, string GroupName)
        {
            string ADServer = GetAppSetting(@"ADServer");
            string ADAdminUser = GetAppSetting(@"ADUser");
            string ADAdminPassword = GetAppSetting(@"ADPass");

            return IsExistUserInGroup(ref IsExist, uid, ADServer, ADAdminUser, ADAdminPassword, GroupName);
        }

        public Exception IsExistUserInGroup(ref Boolean IsExist, string uid, string ADServer, string ADAdminUser, string ADAdminPassword, string GroupName)
        {
            Exception ret = null;
            IsExist = false;
            try
            {
                DirectoryEntry de = new DirectoryEntry(ADServer, ADAdminUser, ADAdminPassword);
                DirectorySearcher deSearch = new DirectorySearcher();
                deSearch.SearchRoot = de;
                deSearch.Filter = "(&(objectClass=group)(cn=" + GroupName + "))";

                SearchResult results = deSearch.FindOne();
                if (results != null)
                {
                    DirectoryEntry deGroup = new DirectoryEntry(results.Path, ADAdminUser, ADAdminPassword, AuthenticationTypes.Secure);
                    System.DirectoryServices.PropertyCollection pcoll = deGroup.Properties;
                    int n = pcoll["member"].Count;

                    for (int l = 0; l < n; l++)
                    {
                        DirectoryEntry deUser =
                            new DirectoryEntry(ADServer +
                                "/" + pcoll["member"][l].ToString()
                                    , ADAdminUser, ADAdminPassword, AuthenticationTypes.Secure);

                        string Login = GetProperty(deUser, "SAMACCOUNTNAME");
                        string USERACCOUNTCONTROL = GetProperty(deUser, "USERACCOUNTCONTROL");
                        deUser.Close();

                        if (USERACCOUNTCONTROL == "512" || USERACCOUNTCONTROL == "66048")
                        {
                            if (uid.ToUpper() == Login.ToUpper())
                            {
                                IsExist = true;
                                break;
                            }
                        }
                    }
                    de.Close();
                    deGroup.Close();
                }
            }
            catch (Exception err)
            {
                ret = new Exception(err.Message, err);
            }
            return ret;
        }

        public Exception GetUsersInGroup(ref DataTable tbUser, string GroupName)
        {
            string ADServer = GetAppSetting(@"ADServer");
            string ADAdminUser = GetAppSetting(@"ADUser");
            string ADAdminPassword = GetAppSetting(@"ADPass");

            return GetUsersInGroup(ref tbUser, ADServer, ADAdminUser, ADAdminPassword, GroupName);
        }

        public Exception GetUsersInGroup(ref DataTable tbUser, string ADServer, string ADAdminUser, string ADAdminPassword, string GroupName)
        {

            Exception ret = null;

            try
            {
                //String strPath = "LDAP://DC=onecity,DC=corp,DC=fabrikam,DC=com";
                DirectoryEntry de = new DirectoryEntry(ADServer, ADAdminUser, ADAdminPassword);
                DirectorySearcher deSearch = new DirectorySearcher();
                deSearch.SearchRoot = de;
                //deSearch.PropertiesToLoad.Add("cn");
                deSearch.Filter = "(&(objectClass=group)(cn=" + GroupName + "))";

                SearchResult results = deSearch.FindOne();

                //Create a new table object within the dataset
                tbUser = new DataTable("Users");
                tbUser.Columns.Add("Login");
                tbUser.Columns.Add("USERACCOUNTCONTROL");
                tbUser.Columns.Add("UserName");
                tbUser.Columns.Add("DisplayName");
                tbUser.Columns.Add("EMailAddress");

                //Create default row
                DataRow rwDefaultUser = tbUser.NewRow();
                rwDefaultUser["Login"] = "(Not Specified)";
                rwDefaultUser["UserName"] = "0";
                rwDefaultUser["DisplayName"] = "(Not Specified)";
                rwDefaultUser["EMailAddress"] = "(Not Specified)";
                tbUser.Rows.Add(rwDefaultUser);

                //if the group is valid, then continue, otherwise return a blank dataset
                if (results != null)
                {
                    //create a link to the group object, so we can get the list of members
                    //within the group
                    DirectoryEntry deGroup = new DirectoryEntry(results.Path, ADAdminUser, ADAdminPassword, AuthenticationTypes.Secure);
                    //assign a property collection
                    System.DirectoryServices.PropertyCollection pcoll = deGroup.Properties;
                    int n = pcoll["member"].Count;

                    //if there are members fo the group, then get the details and assign to the table
                    for (int l = 0; l < n; l++)
                    {
                        //create a link to the user object sot hat the FirstName, LastName and SUername can be gotten
                        DirectoryEntry deUser = new DirectoryEntry(ADServer + "/" + pcoll["member"][l].ToString(), ADAdminUser, ADAdminPassword, AuthenticationTypes.Secure);

                        //set a new empty row
                        DataRow rwUser = tbUser.NewRow();

                        //populate the column
                        rwUser["Login"] = GetProperty(deUser, "SAMACCOUNTNAME");
                        rwUser["USERACCOUNTCONTROL"] = GetProperty(deUser, "USERACCOUNTCONTROL");
                        rwUser["UserName"] = GetProperty(deUser, "cn");
                        rwUser["DisplayName"] = GetProperty(deUser, "givenName") + " " + GetProperty(deUser, "sn");
                        rwUser["EMailAddress"] = GetProperty(deUser, "mail");
                        //append the row to the table of the dataset
                        tbUser.Rows.Add(rwUser);

                        //close the directory entry object
                        deUser.Close();

                    }
                    de.Close();
                    deGroup.Close();
                }
            }
            catch (Exception err)
            {
                ret = new Exception(err.Message, err);
            }
            return ret;
        }

        public string GetProperty(DirectoryEntry oDE, string PropertyName)
        {
            if (oDE.Properties.Contains(PropertyName))
            {
                return oDE.Properties[PropertyName][0].ToString();
            }
            else
            {
                return string.Empty;
            }
        }

    }
}
